API Gatewayを通過しないリクエストをAWS WAFにてブロックしてみた
こんにちは、AWS事業本部の荒平(@0Air)です。
タイトル通り、API Gatewayを通過しないリクエストをAWS WAFでブロックして、ALBへの直接アクセスを防いでみました。
本構成の経緯として、以下のブログにてAPI Gateway+NLB+ALBの構成を実装していたのですが、アプリケーション側から見たアクセス元がNLBのインターナルなIPアドレスとなってしまい、アプリケーション側で不具合が出てしまったため、別の方策を考える必要がありました。
今回紹介する方法を使えば、バックエンド側から見たアクセス元はAPI GatewayのIPとなり、ローカルアクセスの判定をされません。また、最低限のセキュリティを担保するために、ALBへの不特定アクセスを回避します。
構成図
今回の実装では、API GatewayのNLB統合を利用せずに、ALB側でもセキュリティグループをオープンにする方法で解決を目指しました。
API Gatewayを通過するリクエストは、x-amzn-apigateway-api-id
というヘッダーが付与される仕様を利用します。
やってみた
1. 事前準備(API Gateway・ALB/Lambdaの作成)
ALBを作成し、HTTP:80を0.0.0.0/0
に向けて開放します。Target Groupは今回Lambdaを指定して作成しました。
ターゲット先のLambdaサンプルは以下のようにしました。BODYとヘッダーの情報を返すシンプルなものです。
import json def lambda_handler(event, context): body = event.get("body") headers = event.get("headers") response = { "statusCode": 200, "body": json.dumps({ "received_body": body, "received_headers": headers }), "headers": { "Content-Type": "application/json" } } return response
API Gatewayをデプロイし、GETメソッドのリクエスト先に作成したALBを設定します。
API GatewayのIDは後ほど利用するため、控えておきます。
(例:ARNがarn:aws:execute-api:ap-northeast-1:{アカウントID}:bjon5wzrpd/* の場合、bjon5wzrpd
の部分)
2. AWS WAFルールの設定
AWS WAFのコンソールに移動し、Web ACLを作成します。
ここでは、東京リージョンにALBがあるためAsia Pacific (Tokyo)
を選択します。
適当なWeb ACL名を入力し、Add AWS resources
をクリックします。
作成したApplication Load Balancerを選択し、Addをクリックします。
Default web ACL actionをBlock
に設定の上、「Add my own rules and rule groups」をクリックします。
「Rule builder」を選択し、任意のルール名を入力します。
If a requestは「matches the statement」を選択し、ステートメントは以下のように設定します。
項目 | 値 |
---|---|
Inspect | Single header |
Header filed name | x-amzn-apigateway-api-id |
Match type | Exactly matches string |
String to match | {API GatewayのID} |
これ以外の設定は特に変える必要はありません(環境に応じて変更可)。
3. 経由アクセス・直接アクセスの確認
API Gatewayを経由したアクセスができるか確認します。
user-agent
がAmazonAPIGateway_{API Gateway-ID}の形式になっていて、レスポンスが返っていれば問題なくアクセスできています。
続いて、ALBに直接アクセスができるか確認します。
AWS WAFに設定したヘッダー情報と不一致のため、正しく設定されていれば403 Forbidden
が返るはずです。
ブラウザでALBへの直接アクセスを確認しても、狙い通り403 Forbidden
となりました。
おわりに
軽く調べた感じだと、同様の構成がネット上に転がっていなかったので、あまりメジャーに使われていない気がして投稿してみました。
AWS WAFを組み合わせると色々な制御パターンが可能なので、非常に便利なサービスの一つです。
このエントリが誰かの助けになれば幸いです。
それでは、AWS事業本部 コンサルティング部の荒平(@0Air)がお送りしました!